package com.hxh.generater.springBoot.springboot3_vue3.gen.crud;

import com.hxh.entity.Project;
import com.hxh.entity.ProjectDetail;
import com.hxh.entity.ProjectTableFiledConfig;
import com.hxh.entity.TemplateConfig;
import com.hxh.entity.po.ClassInfo;
import com.hxh.entity.po.FieldName;
import com.hxh.generater.common.remote.SpringbootRemoteUtil;
import com.hxh.generater.springBoot.springboot3_vue3.gen.GenSb3Vue3Util;
import com.hxh.util.Common;
import com.hxh.util.GenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

/**
 * @ProjectName: AICode
 * @Package: com.hxh.generater
 * @Author: HXH
 * @Description:
 * @Date: 2023/11/28 15:08
 */
@Slf4j
public class GenEntityRemote {

    public static void generationOneEntity(Project project, ClassInfo classInfo) throws IOException {
        generationEntityClass(project, classInfo, true);
        generationEntityInputClass(project, classInfo, true);
        generationOneEntityMappingClass(project, classInfo);
    }

    public static String generationEntityClass(String packageName, ClassInfo classInfo, TemplateConfig templateConfig) throws IOException {
        Project project = new Project();
        ProjectDetail backendProject = new ProjectDetail();
        backendProject.setProjectGroup(packageName);
        project.setBackendProject(backendProject);
        project.setTemplateConfig(templateConfig);
        return generationEntityClass(project, classInfo, false);
    }

    public static String generationEntityInputClass(String packageName, ClassInfo classInfo, TemplateConfig templateConfig) throws IOException {
        Project project = new Project();
        ProjectDetail backendProject = new ProjectDetail();
        backendProject.setProjectGroup(packageName);
        project.setBackendProject(backendProject);
        project.setTemplateConfig(templateConfig);
        return generationEntityInputClass(project, classInfo, false);
    }

    /**
     * @param project:
     * @param classInfo:
     * @return void
     * @author HXH
     * @description: 生成实体类
     * @date 2024/5/21
     **/
    private static String generationEntityClass(Project project, ClassInfo classInfo, boolean writeFile) throws IOException {
        String className = classInfo.getClassName();

        SpringbootRemoteUtil springbootRemoteUtil = new SpringbootRemoteUtil();
        springbootRemoteUtil.setProject(project);
        springbootRemoteUtil.setClassInfo(classInfo);
        springbootRemoteUtil.setWriteFile(writeFile);
        springbootRemoteUtil.setRemoteUrlSuffix("springboot/entity");
        springbootRemoteUtil.setWriteFileName(className);
        String mutilDatasourcePathName = GenUtil.getMutilDatasourceStrByConfig(project, classInfo, "", File.separator);
        springbootRemoteUtil.setWriteFilePath("model\\entity\\" + mutilDatasourcePathName);
        String projectNamePath = "";
        if (project != null) {
            projectNamePath = project.getName() + "\\";
        }
        String classNameEntity = StringUtils.uncapitalize(className);
        springbootRemoteUtil.setAdditionFilePath(GenSb3Vue3Util.FILE_PATH_PRE + "addition\\" + projectNamePath + "entity\\" + classNameEntity);
        return springbootRemoteUtil.process();
    }

    /**
     * @param project:
     * @param classInfo:
     * @return void
     * @author HXH
     * @description: 生成实体类的input对象代码
     * @date 2024/5/21
     **/
    private static String generationEntityInputClass(Project project, ClassInfo classInfo, boolean writeFile) throws IOException {
        String className = classInfo.getClassName() + "Query";

        SpringbootRemoteUtil springbootRemoteUtil = new SpringbootRemoteUtil();
        springbootRemoteUtil.setProject(project);
        springbootRemoteUtil.setClassInfo(classInfo);
        springbootRemoteUtil.setWriteFile(writeFile);
        springbootRemoteUtil.setRemoteUrlSuffix("springboot/entityInput");
        springbootRemoteUtil.setWriteFileName(className);
        String mutilDatasourcePathName = GenUtil.getMutilDatasourceStrByConfig(project, classInfo, "", File.separator);
        springbootRemoteUtil.setWriteFilePath("model\\query\\" + mutilDatasourcePathName);

        String projectNamePath = "";
        if (project != null) {
            projectNamePath = project.getName() + "\\";
        }
        String classNameEntity = StringUtils.uncapitalize(className);
        springbootRemoteUtil.setAdditionFilePath(GenSb3Vue3Util.FILE_PATH_PRE + "addition\\" + projectNamePath + "entityQuery\\" + classNameEntity);
        return springbootRemoteUtil.process();

    }

    public static void generationOneEntityMappingClass(Project project, ClassInfo classInfo) throws IOException {
        List<FieldName> fieldNames = classInfo.getFieldNameList();
        String className = classInfo.getClassName();
        String mappingClassName = className + "Mapping";
        String mutilDatasourcePathName = GenUtil.getMutilDatasourceStrByConfig(project, classInfo, "", File.separator);
        File classFile = GenUtil.newFile(project, "model\\entity\\mapping\\" + mutilDatasourcePathName, mappingClassName);

        try {
            FileWriter fileWriter = new FileWriter(classFile);
            BufferedWriter writer = new BufferedWriter(fileWriter);
            String packageMutilDatasourceStr = GenUtil.getMutilDatasourceStrByConfig(project, classInfo, ".", null);
            // 在这里写入文件
            writer.write("package " + project.getBackendProject().getProjectGroup() + ".model.entity.mapping" + packageMutilDatasourceStr + ";");
            writer.newLine();
            writer.write("import java.util.ArrayList;");
            writer.newLine();
            writer.write("import java.util.List;");
            writer.newLine();
            writer.write("import com.alibaba.fastjson.JSONObject;");
            writer.newLine();
            writer.write("import com.alibaba.fastjson.JSON;");
            writer.newLine();
            writer.newLine();
            writer.write("/**");
            writer.newLine();
            writer.write(" * " + classInfo.getDesc() + " 字段映射配置");
            writer.newLine();
            writer.write(" **/");
            writer.newLine();
            writer.write("public class " + mappingClassName + " {");
            writer.newLine();

            writer.write("    public static final String entityName = \"" + className + "\";");
            writer.newLine();
            writer.write("    public static final String tableName = \"" + classInfo.getTableName() + "\";");
            writer.newLine();
            writer.write("    public static final String tableDesc = \"" + classInfo.getDesc() + "\";");
            writer.newLine();
            writer.newLine();
            writer.write("    public static final List<JSONObject> fieldInfoList = new ArrayList<>();");
            writer.newLine();
            writer.newLine();
            writer.write("    static {");
            for (FieldName fieldName : fieldNames) {
                writer.newLine();
                String jsonName = fieldName.getJavaName() + "JsonObject";
                String radioOptionName = fieldName.getJavaName() + "RadioOption";

                writer.write("        JSONObject " + jsonName + " = new JSONObject();");
                writer.newLine();
                writer.write("        " + jsonName + ".put(\"fieldName\",\"" + fieldName.getName() + "\");");
                writer.newLine();
                writer.write("        " + jsonName + ".put(\"javaName\",\"" + fieldName.getJavaName() + "\");");
                writer.newLine();

                String showName = fieldName.getDesc();
                String type = "text";
                String showSelectOption = null;
                String associationTable = null;
                String collectionTable = null;
                ProjectTableFiledConfig pfc = fieldName.getProjectTableFiledConfig();
                if (pfc != null) {
                    String configName = pfc.getShowName();
                    showName = Common.getStringNotNull(configName, showName);
//                    类型: text, textarea, number, radio, checkbox, date,dateTime, file, img
                    type = pfc.getShowType();
                    showSelectOption = pfc.getShowSelectOption();
                    associationTable = pfc.getAssociationTable();
                    collectionTable = pfc.getCollectionTable();
                }
                showName = showName.replaceAll("\\r?\\n", " ");
                showName = showName.replaceAll("\"", "\\\\\"");
                writer.write("        " + jsonName + ".put(\"desc\",\"" + showName + "\");");
                writer.newLine();

                writer.write("        " + jsonName + ".put(\"type\",\"" + type + "\");");
                writer.newLine();
                if (StringUtils.isNotBlank(showSelectOption)) {
                    String radioOptionNameReverseName = radioOptionName + "Reverse";
                    showSelectOption = showSelectOption.replaceAll("\"", "\\\\\"");
                    writer.write("        JSONObject " + radioOptionName + " = JSON.parseObject(\"" + showSelectOption + "\");");
                    writer.newLine();
                    writer.write("        " + jsonName + ".put(\"radioOption\"," + radioOptionName + ");");
                    writer.newLine();
                    writer.write("        JSONObject " + radioOptionNameReverseName + " = new JSONObject();");
                    writer.newLine();
                    writer.write("        for (String key : " + radioOptionName + ".keySet()) {");
                    writer.newLine();
                    writer.write("            " + radioOptionNameReverseName + ".put(" + radioOptionName + ".getString(key),key);");
                    writer.newLine();
                    writer.write("        }");
                    writer.newLine();
                    writer.write("        " + jsonName + ".put(\"radioOptionReverse\"," + radioOptionNameReverseName + ");");
                    writer.newLine();
                } else if (StringUtils.isNotBlank(associationTable)) {
                    String associationName = fieldName.getJavaName() + "Association";
                    associationTable = associationTable.replaceAll("\"", "\\\\\"");
                    writer.write("        JSONObject " + associationName + " = JSON.parseObject(\"" + associationTable + "\");");
                    writer.newLine();
                    writer.write("        " + jsonName + ".put(\"associationTable\"," + associationName + ");");
                    writer.newLine();
                } else if (StringUtils.isNotBlank(collectionTable)) {
                    String collectionName = fieldName.getJavaName() + "Collection";
                    collectionTable = collectionTable.replaceAll("\"", "\\\\\"");
                    writer.write("        JSONObject " + collectionName + " = JSON.parseObject(\"" + collectionTable + "\");");
                    writer.newLine();
                    writer.write("        " + jsonName + ".put(\"collectionTable\"," + collectionName + ");");
                    writer.newLine();
                }
                writer.write("        fieldInfoList.add(" + jsonName + ");");
                writer.newLine();
            }
            writer.write("    }");
            writer.newLine();
            writer.write("}");
            writer.close();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
